﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using blacksoft.Models;
using System.Data.Entity.Core.Objects;
using blacksoft.Constantes;

namespace blacksoft.Controllers
{
    public class ProgramacionViajeController : Controller
    {
        private inf245travelbusEntities db = new inf245travelbusEntities();

        //Tipos de serivicio posibles
        private class Servicio
        {
            public int valor { get; set; }
            public string nombre { get; set; }

            public Servicio(int valor, string nombre)
            {
                this.valor = valor;
                this.nombre = nombre;
            }
        }
        private List<Servicio> tipos_servicio = new List<Servicio> { new Servicio(1, "Económico"), new Servicio(2, "VIP") };

        // GET: /ProgramacionViaje/
        public ActionResult Index(string search_tipo, string search_estado)
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            

            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            //Seleccionar todas las reservas del día
            var viajes = from v in db.ProgramacionViaje
                         where v.Estado != "AN"
                         select v;
            //Local session
            int idTerminal;
            if (!global)
            {
                idTerminal = (int)Session["IDTerminal"];
                viajes = from pv in viajes 
                        join r_b in db.Ruta_x_UnidadTransporte on pv.IdRuta_x_UnidadTransporte equals r_b.IdRuta_x_UnidadTransporte
                        join r in db.Ruta on r_b.IDRuta equals r.IDRuta
                        where r.IDTerminal == idTerminal
                        select pv;
            }


            ViewBag.search_tipo = new SelectList(tipos_servicio, "valor", "nombre");
            if (!String.IsNullOrEmpty(search_tipo))
            {
                int tipo = int.Parse(search_tipo);
                viajes = viajes.Where(s => s.TipoServicio == tipo);
            }

            var lista_estados = new List<string>();
            var estados_qry = from d in db.ProgramacionViaje
                              where d.Estado != "AN"
                              orderby d.Estado 
                              select d.Estado;
            lista_estados.AddRange(estados_qry.Distinct());
            ViewBag.search_estado = new SelectList(lista_estados);

            if (!string.IsNullOrEmpty(search_estado))
            {
                viajes = viajes.Where(x => x.Estado == search_estado);
            }

            return View(viajes); 
        }

        // GET: /ProgramacionViaje/Details/5
        public ActionResult Details(int? id)
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }


            try
            {

                ProgramacionViaje programacionviaje = db.ProgramacionViaje.Find(id);
                if (programacionviaje == null)
                {
                    return HttpNotFound();
                }

                //Cargar los productos necesarios
                var lst_productos = new List<ART_ProductoDetails>();
                var qry_productos = from p in db.Producto
                                    where p.EnViaje == true
                                    select p;
                var qry_pasajes = from pa in db.Pasaje
                                  where pa.IDProgramacionViaje == programacionviaje.IDProgramacionViaje
                                  select pa;
                int cantidad_pasajes = qry_pasajes.Count(); //se determina la cantidad de pasajes para poder calcular los productos
                foreach (var producto in qry_productos)
                {
                    ART_ProductoDetails art_pro = new ART_ProductoDetails();
                    art_pro.IDProducto = producto.IDProducto;
                    art_pro.Nombre = producto.Nombre;
                    art_pro.Descripcion = producto.Descripcion;
                    art_pro.Cantidad = cantidad_pasajes;
                    art_pro.UnidadMedida = producto.UnidadMedida;
                    lst_productos.Add(art_pro);
                }
                programacionviaje.Productos = lst_productos;

                //Cargar choferes al viaje
                var lst_choferes = new List<ART_ChoferDetails>();
                var qry_choferes = from p in db.ProgramacionViaje_x_Personal
                                   join ch in db.Persona on p.IDPersona equals ch.IDPersona
                                   where p.IDProgramacionViaje == programacionviaje.IDProgramacionViaje && ch.CargoPersonal == "Chofer"
                                   select ch;
                //qry_choferes = qry_choferes.Where(p => p.IDTerminal == X);
                foreach (var chofer in qry_choferes)
                {
                    ART_ChoferDetails art_chofer = new ART_ChoferDetails();
                    art_chofer.IDPersona = chofer.IDPersona;
                    art_chofer.ApellidoPaterno = chofer.ApellidoPaterno;
                    art_chofer.ApellidoMaterno = chofer.ApellidoMaterno;
                    art_chofer.Nombre = chofer.Nombre;
                    art_chofer.DNI = chofer.DNI;
                    art_chofer.Telefono = chofer.Telefono;
                    art_chofer.CargoPersonal = chofer.CargoPersonal;
                    art_chofer.Estado = chofer.Estado;
                    lst_choferes.Add(art_chofer);
                }
                programacionviaje.Choferes_Details = lst_choferes;

                //Cargar terramozas(os) al viaje
                var lst_terramozas = new List<ART_TerramozaDetails>();
                var qry_terramozas = from p in db.ProgramacionViaje_x_Personal
                                     join te in db.Persona on p.IDPersona equals te.IDPersona
                                     where p.IDProgramacionViaje == programacionviaje.IDProgramacionViaje && te.CargoPersonal == "Terramoza/o"
                                     select te;
                //qry_choferes = qry_choferes.Where(p => p.IDTerminal == X);
                foreach (var terramoza in qry_terramozas)
                {
                    ART_TerramozaDetails art_terramoza = new ART_TerramozaDetails();
                    art_terramoza.IDPersona = terramoza.IDPersona;
                    art_terramoza.ApellidoPaterno = terramoza.ApellidoPaterno;
                    art_terramoza.ApellidoMaterno = terramoza.ApellidoMaterno;
                    art_terramoza.Nombre = terramoza.Nombre;
                    art_terramoza.DNI = terramoza.DNI;
                    art_terramoza.Telefono = terramoza.Telefono;
                    art_terramoza.CargoPersonal = terramoza.CargoPersonal;
                    art_terramoza.Estado = terramoza.Estado;
                    lst_terramozas.Add(art_terramoza);
                }
                programacionviaje.Terramozas_Details = lst_terramozas;

                //Cargar buses al viaje
                var lst_buses = new List<ART_BusRutaDetails>();
                var qry_busesxruta = from ru_bu in db.Ruta_x_UnidadTransporte
                                     join bu in db.UnidadTransporte on ru_bu.IDUnidadTransporte equals bu.IDUnidadTransporte
                                     join ru in db.Ruta on ru_bu.IDRuta equals ru.IDRuta
                                     where ru_bu.IdRuta_x_UnidadTransporte == programacionviaje.IdRuta_x_UnidadTransporte && ru_bu.Estado == "AC" //&& ru.IDTerminal == X && bu.IDTerminal == X
                                     select new { ru_bu.IdRuta_x_UnidadTransporte, ru_bu.IDUnidadTransporte, ru_bu.IDRuta, ru_bu.Estado };
                foreach (var busxruta in qry_busesxruta)
                {
                    UnidadTransporte bus = db.UnidadTransporte.Find(busxruta.IDUnidadTransporte);
                    Ruta ruta = db.Ruta.Find(busxruta.IDRuta);
                    ART_BusRutaDetails art_bus = new ART_BusRutaDetails();
                    art_bus.IDUnidadTransporte = bus.IDUnidadTransporte;
                    art_bus.NumeroPlaca = bus.NumeroPlaca;
                    art_bus.AñoFabricacion = bus.AñoFabricacion;
                    art_bus.TipoServicio = bus.TipoServicio;
                    art_bus.Ruta = ruta.TerminalOrigen + "-" + ruta.TerminalDestino;
                    art_bus.Estado = busxruta.Estado;
                    lst_buses.Add(art_bus);
                }
                programacionviaje.Buses_Details = lst_buses;

                //Cargar promociones del viaje
                var lst_promociones = new List<ART_PromocionDetails>();
                var qry_promociones = from prom_progv in db.Promocion_ProgramacionViaje
                                      join prom in db.Promocion on prom_progv.IdPromocion equals prom.IdPromocion
                                      where programacionviaje.IDProgramacionViaje == prom_progv.IDProgramacionViaje && prom.Estado == "AC" //&& prom.FechaFin >= DateTime.Now
                                      select prom;
                //qry_promociones = qry_promociones.Where(p => p.IDTerminal == X);
                foreach (var promocion in qry_promociones)
                {
                    ART_PromocionDetails art_prom = new ART_PromocionDetails();
                    art_prom.IdPromocion = promocion.IdPromocion;
                    art_prom.Descripcion = promocion.Descripcion;
                    art_prom.Estado = promocion.Estado;
                    art_prom.FechaFin = promocion.FechaFin;
                    art_prom.FechaInicio = promocion.FechaInicio;
                    art_prom.PorcentajeDescuento = promocion.PorcentajeDescuento;
                    art_prom.PuntosRequeridos = promocion.PuntosRequeridos;
                    art_prom.TipoCliente = promocion.TipoCliente;
                    lst_promociones.Add(art_prom);
                }
                programacionviaje.Promociones_Details = lst_promociones;

                return View(programacionviaje);
            }
            catch
            {
                TempData["details_failure"] = "No se encontró la programción viaje";
                return RedirectToAction("Index");
            }
        }

        // GET: /ProgramacionViaje/Create
        public ActionResult Create()
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            ProgramacionViaje prog_viaje = new ProgramacionViaje();
            //BUSQUEDA DE BUSES SEGÚN EL TERMINAL DEL OPERADOR
            int id_terminal = (int)Session["IDTerminal"];
            var lst_buses = new List<ART_BusRutaEnViaje>();
            var qry_busesxruta = from ru_bu in db.Ruta_x_UnidadTransporte
                                 join bu in db.UnidadTransporte on ru_bu.IDUnidadTransporte equals bu.IDUnidadTransporte
                                 join ru in db.Ruta on ru_bu.IDRuta equals ru.IDRuta
                                 where ru_bu.Estado == "AC" && ru.IDTerminal == id_terminal && bu.IDTerminal == id_terminal
                                 select new{ru_bu.IdRuta_x_UnidadTransporte, ru_bu.IDUnidadTransporte, ru_bu.IDRuta, ru_bu.Estado};
            foreach (var busxruta in qry_busesxruta)
            {
                UnidadTransporte bus = db.UnidadTransporte.Find(busxruta.IDUnidadTransporte);
                Ruta ruta = db.Ruta.Find(busxruta.IDRuta);
                ART_BusRutaEnViaje art_bus = new ART_BusRutaEnViaje();
                art_bus.IDUnidadTransporte = bus.IDUnidadTransporte;
                art_bus.Elegido = false;
                art_bus.NumeroPlaca = bus.NumeroPlaca;
                art_bus.AñoFabricacion = bus.AñoFabricacion;
                art_bus.TipoServicio = bus.TipoServicio;
                art_bus.Ruta = ruta.TerminalOrigen + "-" + ruta.TerminalDestino;
                art_bus.Estado = busxruta.Estado;
                art_bus.IDRutaxBus = (int)busxruta.IdRuta_x_UnidadTransporte;
                //art_chofer.CargoPersonal = chofer.CargoPersonal;
                //art_chofer.Estado = chofer.Estado;
                lst_buses.Add(art_bus);
            }
            prog_viaje.Buses = lst_buses;
            //BUSQUEDA DE CHOFERES SEGÚN EL TERMINAL DEL OPERADOR
            var lst_choferes = new List<ART_ChoferEnViaje>();
            var qry_choferes = from per in db.Persona
                           where per.Estado == "AC" && per.CargoPersonal == "Chofer"
                           select per;
            qry_choferes = qry_choferes.Where(p => p.IDTerminal == id_terminal);
            foreach (var chofer in qry_choferes)
            {
                ART_ChoferEnViaje art_chofer = new ART_ChoferEnViaje();
                art_chofer.IDPersona = chofer.IDPersona;
                art_chofer.Elegido = false;
                art_chofer.ApellidoPaterno = chofer.ApellidoPaterno;
                art_chofer.ApellidoMaterno = chofer.ApellidoMaterno;
                art_chofer.Nombre = chofer.Nombre;
                art_chofer.DNI = chofer.DNI;
                art_chofer.Telefono = chofer.Telefono;
                art_chofer.CargoPersonal = chofer.CargoPersonal;
                art_chofer.Estado = chofer.Estado;
                lst_choferes.Add(art_chofer);
            }
            prog_viaje.Choferes = lst_choferes;
            //BUSQUEDA DE TERRAMOZAS SEGÚN EL TERMINAL DEL OPERADOR
            var lst_terramozas = new List<ART_TerramozaEnViaje>();
            var qry_terramozas = from per in db.Persona
                                 where per.Estado == "AC" && per.CargoPersonal == "Terramoza/o"
                                 select per;
            qry_terramozas = qry_terramozas.Where(p => p.IDTerminal == id_terminal);
            foreach (var terramoza in qry_terramozas)
            {
                ART_TerramozaEnViaje art_terramoza = new ART_TerramozaEnViaje();
                art_terramoza.IDPersona = terramoza.IDPersona;
                art_terramoza.Elegido = false;
                art_terramoza.ApellidoPaterno = terramoza.ApellidoPaterno;
                art_terramoza.ApellidoMaterno = terramoza.ApellidoMaterno;
                art_terramoza.Nombre = terramoza.Nombre;
                art_terramoza.DNI = terramoza.DNI;
                art_terramoza.CargoPersonal = terramoza.CargoPersonal;
                art_terramoza.Telefono = terramoza.Telefono;
                art_terramoza.Estado = terramoza.Estado;
                lst_terramozas.Add(art_terramoza);
            }
            prog_viaje.Terramozas = lst_terramozas;
            //BUSQUEDA DE PROMOCIONES SEGÚN EL TERMINAL DEL OPERADOR
            var lst_promociones = new List<ART_PromocionEnViaje>();
            var qry_promociones = from prom in db.Promocion
                                          where prom.Estado == "AC" && prom.FechaFin>=DateTime.Now
                                          select prom;
            qry_promociones = qry_promociones.Where(p => p.IDTerminal == id_terminal);
            foreach (var promocion in qry_promociones)
            {
                ART_PromocionEnViaje art_prom = new ART_PromocionEnViaje();
                art_prom.IdPromocion = promocion.IdPromocion;
                art_prom.Elegido = false;
                art_prom.Descripcion = promocion.Descripcion;
                art_prom.Estado = promocion.Estado;
                art_prom.FechaFin = promocion.FechaFin;
                art_prom.FechaInicio = promocion.FechaInicio;
                art_prom.PorcentajeDescuento = promocion.PorcentajeDescuento;
                art_prom.PuntosRequeridos = promocion.PuntosRequeridos;
                art_prom.TipoCliente = promocion.TipoCliente;
                lst_promociones.Add(art_prom);
            }
            prog_viaje.Promociones = lst_promociones;

            return View(prog_viaje);
        }

        // POST: /ProgramacionViaje/Create
        // Para protegerse de ataques de publicación excesiva, habilite las propiedades específicas a las que desea enlazarse. Para obtener 
        // más información vea http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "IDProgramacionViaje,Choferes,Buses,Terramozas,Promociones,FechaSalida,Descripcion,CapacidadPasajeros,TipoServicio,Precio,Estado,FechaLlegada")] ProgramacionViaje programacionviaje)
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            //validar fechas desde y hasta 
            if (programacionviaje.FechaSalida > programacionviaje.FechaLlegada)
            {
                ModelState.AddModelError("ErrorFechaSalida", "El campo Fecha de Salida no puede ser mayor al campo Fecha de Llegada");
                return View(programacionviaje);
            }

            if (ModelState.IsValid)
            {               
                //validar choferes
                var choferes_seleccionados = programacionviaje.Choferes.Where(s => s.Elegido == true);
                if (choferes_seleccionados.Count() < 1)
                {
                    ModelState.AddModelError("ErrorMinChoferes", "Debe seleccionar como mínimo un Chofer");
                    return View(programacionviaje);
                }
                //validar terramozos
                var terramozos_seleccionados = programacionviaje.Terramozas.Where(s => s.Elegido == true);
                if (terramozos_seleccionados.Count() < 1)
                {
                    ModelState.AddModelError("ErrorMinTerramozos", "Debe seleccionar como mínimo una Terramoza/o");
                    return View(programacionviaje);
                }
                //validar buses
                var buses_seleccionados = programacionviaje.Buses.Where(s => s.Elegido == true);
                if (buses_seleccionados.Count() == 0 || buses_seleccionados.Count() >= 2)
                {
                    ModelState.AddModelError("ErrorMinBuses", "Debe seleccionar un Bus");
                    return View(programacionviaje);
                }

                DateTime aux_fechasalida = (DateTime)programacionviaje.FechaSalida;
                DateTime aux_fechallegada = (DateTime)programacionviaje.FechaLlegada;
                //DateTime aux_fechahasta = (DateTime)programacionviaje.FechaHasta;

                //while (aux_fechasalida.Date.CompareTo(aux_fechahasta.Date) <= 0)
                //{
                    //salvar viaje anterior
                    ProgramacionViaje programacionviaje_anterior = programacionviaje;
                    //Asignación de buses a viajes
                    foreach (var bus in programacionviaje.Buses)
                    {
                        if (bus.Elegido)
                        {
                            //Guardar la Ruta_x_UnidadTrasporte 
                            programacionviaje.IdRuta_x_UnidadTransporte = bus.IDRutaxBus;
                            programacionviaje.Ruta_x_UnidadTransporte = db.Ruta_x_UnidadTransporte.Find(programacionviaje.IdRuta_x_UnidadTransporte);
                        }
                    }
                    //Asignación de choferes a viajes
                    foreach (var chofer in programacionviaje.Choferes)
                    {
                        if (chofer.Elegido)
                        {
                            //Guardar en ProgramacionViaje_x_Personal
                            ProgramacionViaje_x_Personal per_progviaje = new ProgramacionViaje_x_Personal();
                            per_progviaje.IDPersona = chofer.IDPersona;
                            per_progviaje.IDProgramacionViaje = programacionviaje.IDProgramacionViaje;
                            per_progviaje.Estado = "AC";
                            db.ProgramacionViaje_x_Personal.Add(per_progviaje);
                        }
                    }
                    //Asignación de terramozas(os) a viajes
                    foreach (var prom in programacionviaje.Terramozas)
                    {
                        if (prom.Elegido)
                        {
                            //Guardar en ProgramacionViaje_x_Personal
                            ProgramacionViaje_x_Personal per_progviaje = new ProgramacionViaje_x_Personal();
                            per_progviaje.IDPersona = prom.IDPersona;
                            per_progviaje.IDProgramacionViaje = programacionviaje.IDProgramacionViaje;
                            per_progviaje.Estado = "AC";
                            db.ProgramacionViaje_x_Personal.Add(per_progviaje);
                        }
                    }
                    //Asignación de promociones a viajes
                    foreach (var prom in programacionviaje.Promociones)
                    {
                        if (prom.Elegido)
                        {
                            //Guardar en Promocion_x_ProgramacionViaje
                            Promocion_ProgramacionViaje prom_progviaje = new Promocion_ProgramacionViaje();
                            prom_progviaje.IdPromocion = prom.IdPromocion;
                            prom_progviaje.IDProgramacionViaje = programacionviaje.IDProgramacionViaje;
                            prom_progviaje.Estado = "AC";
                            db.Promocion_ProgramacionViaje.Add(prom_progviaje);
                        }
                    }
                    programacionviaje.FechaSalida = aux_fechasalida;
                    programacionviaje.FechaLlegada = aux_fechallegada;
                    db.ProgramacionViaje.Add(programacionviaje);
                //    programacionviaje = new ProgramacionViaje();
                //    aux_fechasalida = aux_fechasalida.AddDays(1);
                //    aux_fechallegada= aux_fechallegada.AddDays(1);
                //    programacionviaje.CapacidadPasajeros = programacionviaje_anterior.CapacidadPasajeros;
                //    programacionviaje.Descripcion = programacionviaje_anterior.Descripcion;
                //    programacionviaje.FechaHasta = programacionviaje_anterior.FechaHasta;
                //    programacionviaje.Precio = programacionviaje_anterior.Precio;
                //    programacionviaje.TipoServicio = programacionviaje_anterior.TipoServicio;
                //    programacionviaje.Buses = programacionviaje_anterior.Buses;
                //    programacionviaje.Choferes = programacionviaje_anterior.Choferes;
                //    programacionviaje.Terramozas = programacionviaje_anterior.Terramozas;
                //    programacionviaje.Promociones = programacionviaje_anterior.Promociones;
                //}
                try
                {
                    db.SaveChanges();
                }
                catch
                {
                    TempData["create_failure"] = "El viaje no se pudo registrar";
                    return RedirectToAction("Index");
                }
                TempData["create_success"] = "El viaje se registró exitosamente";
                return RedirectToAction("Index");
            }

            return View(programacionviaje);
        }

        // GET: /ProgramacionViaje/Edit/5
        public ActionResult Edit(int? id)
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            try
            {
                ProgramacionViaje programacionviaje = db.ProgramacionViaje.Find(id);
                if (programacionviaje == null)
                {
                    return HttpNotFound();
                }

                //Cargar los productos necesarios
                var lst_productos = new List<ART_ProductoDetails>();
                var qry_productos = from p in db.Producto
                                    where p.EnViaje == true
                                    select p;
                var qry_pasajes = from pa in db.Pasaje
                                  where pa.IDProgramacionViaje == programacionviaje.IDProgramacionViaje
                                  select pa;
                int cantidad_pasajes = qry_pasajes.Count(); //se determina la cantidad de pasajes para poder calcular los productos
                foreach (var producto in qry_productos)
                {
                    ART_ProductoDetails art_pro = new ART_ProductoDetails();
                    art_pro.IDProducto = producto.IDProducto;
                    art_pro.Nombre = producto.Nombre;
                    art_pro.Descripcion = producto.Descripcion;
                    art_pro.Cantidad = cantidad_pasajes;
                    art_pro.UnidadMedida = producto.UnidadMedida;
                    lst_productos.Add(art_pro);
                }
                programacionviaje.Productos = lst_productos;


                //BUSQUEDA DE BUSES SEGÚN EL TERMINAL DEL OPERADOR
                int id_terminal = (int)Session["IDTerminal"];
                var lst_buses = new List<ART_BusRutaEnViaje>();
                var qry_busesxruta = from ru_bu in db.Ruta_x_UnidadTransporte
                                     join bu in db.UnidadTransporte on ru_bu.IDUnidadTransporte equals bu.IDUnidadTransporte
                                     join ru in db.Ruta on ru_bu.IDRuta equals ru.IDRuta
                                     where ru_bu.Estado == "AC" && ru.IDTerminal == id_terminal && bu.IDTerminal == id_terminal
                                     select new { ru_bu.IdRuta_x_UnidadTransporte, ru_bu.IDUnidadTransporte, ru_bu.IDRuta, ru_bu.Estado };
                foreach (var busxruta in qry_busesxruta)
                {
                    UnidadTransporte bus = db.UnidadTransporte.Find(busxruta.IDUnidadTransporte);
                    Ruta ruta = db.Ruta.Find(busxruta.IDRuta);
                    ART_BusRutaEnViaje art_bus = new ART_BusRutaEnViaje();
                    art_bus.IDUnidadTransporte = bus.IDUnidadTransporte;
                    //Marcar el bus que fue elegido en el viaje 
                    if (busxruta.IdRuta_x_UnidadTransporte == programacionviaje.IdRuta_x_UnidadTransporte)
                        art_bus.Elegido = true;
                    else
                        art_bus.Elegido = false;
                    art_bus.NumeroPlaca = bus.NumeroPlaca;
                    art_bus.AñoFabricacion = bus.AñoFabricacion;
                    art_bus.TipoServicio = bus.TipoServicio;
                    art_bus.Ruta = ruta.TerminalOrigen + "-" + ruta.TerminalDestino;
                    art_bus.Estado = busxruta.Estado;
                    art_bus.IDRutaxBus = (int)busxruta.IdRuta_x_UnidadTransporte;
                    //art_chofer.CargoPersonal = chofer.CargoPersonal;
                    //art_chofer.Estado = chofer.Estado;
                    lst_buses.Add(art_bus);
                }
                programacionviaje.Buses = lst_buses;

                //BUSQUEDA DE CHOFERES SEGÚN EL TERMINAL DEL OPERADOR
                var lst_choferes = new List<ART_ChoferEnViaje>();
                var qry_choferes = from per in db.Persona
                                   where per.Estado == "AC" && per.CargoPersonal == "Chofer"
                                   select per;
                var qry_choferes_elegidos = from progv_per in db.ProgramacionViaje_x_Personal
                                            join ch in db.Persona on progv_per.IDPersona equals ch.IDPersona
                                            where progv_per.IDProgramacionViaje == programacionviaje.IDProgramacionViaje && progv_per.Estado == "AC" && ch.CargoPersonal == "Chofer"
                                            select ch;
                qry_choferes = qry_choferes.Where(p => p.IDTerminal == id_terminal);
                foreach (var chofer in qry_choferes)
                {
                    ART_ChoferEnViaje art_chofer = new ART_ChoferEnViaje();
                    art_chofer.IDPersona = chofer.IDPersona;
                    //Marcar los choferes que fueron elegidos anteriormente
                    foreach (var item in qry_choferes_elegidos)
                    {
                        if (item.IDPersona == chofer.IDPersona)
                        {
                            art_chofer.Elegido = true;
                            break;
                        }
                    }
                    art_chofer.ApellidoPaterno = chofer.ApellidoPaterno;
                    art_chofer.ApellidoMaterno = chofer.ApellidoMaterno;
                    art_chofer.Nombre = chofer.Nombre;
                    art_chofer.DNI = chofer.DNI;
                    art_chofer.Telefono = chofer.Telefono;
                    art_chofer.CargoPersonal = chofer.CargoPersonal;
                    art_chofer.Estado = chofer.Estado;
                    lst_choferes.Add(art_chofer);
                }
                programacionviaje.Choferes = lst_choferes;

                //BUSQUEDA DE TERRAMOZAS SEGÚN EL TERMINAL DEL OPERADOR
                var lst_terramozas = new List<ART_TerramozaEnViaje>();
                var qry_terramozas = from per in db.Persona
                                     where per.Estado == "AC" && per.CargoPersonal == "Terramoza/o"
                                     select per;
                var qry_terramozas_elegidos = from progv_per in db.ProgramacionViaje_x_Personal
                                              join te in db.Persona on progv_per.IDPersona equals te.IDPersona
                                              where progv_per.IDProgramacionViaje == programacionviaje.IDProgramacionViaje && progv_per.Estado == "AC" && te.CargoPersonal == "Terramoza/o"
                                              select te;
                qry_terramozas = qry_terramozas.Where(p => p.IDTerminal == id_terminal);
                foreach (var terramoza in qry_terramozas)
                {
                    ART_TerramozaEnViaje art_terramoza = new ART_TerramozaEnViaje();
                    art_terramoza.IDPersona = terramoza.IDPersona;
                    //Marcar los terramozos que fueron elegidos anteriormente
                    foreach (var item in qry_terramozas_elegidos)
                    {
                        if (item.IDPersona == terramoza.IDPersona)
                        {
                            art_terramoza.Elegido = true;
                            break;
                        }
                    }
                    art_terramoza.ApellidoPaterno = terramoza.ApellidoPaterno;
                    art_terramoza.ApellidoMaterno = terramoza.ApellidoMaterno;
                    art_terramoza.Nombre = terramoza.Nombre;
                    art_terramoza.DNI = terramoza.DNI;
                    art_terramoza.CargoPersonal = terramoza.CargoPersonal;
                    art_terramoza.Telefono = terramoza.Telefono;
                    art_terramoza.Estado = terramoza.Estado;
                    lst_terramozas.Add(art_terramoza);
                }
                programacionviaje.Terramozas = lst_terramozas;

                //BUSQUEDA DE PROMOCIONES SEGÚN EL TERMINAL DEL OPERADOR
                var lst_promociones = new List<ART_PromocionEnViaje>();
                var qry_promociones = from prom in db.Promocion
                                      where prom.Estado == "AC" && prom.FechaFin >= DateTime.Now
                                      select prom;
                var qry_promociones_elegidas = from prom_progv in db.Promocion_ProgramacionViaje
                                               join prom in db.Promocion on prom_progv.IdPromocion equals prom.IdPromocion
                                               where prom_progv.IDProgramacionViaje == programacionviaje.IDProgramacionViaje && prom_progv.Estado == "AC"
                                               select prom;
                qry_promociones = qry_promociones.Where(p => p.IDTerminal == id_terminal);
                foreach (var promocion in qry_promociones)
                {
                    ART_PromocionEnViaje art_prom = new ART_PromocionEnViaje();
                    art_prom.IdPromocion = promocion.IdPromocion;
                    //Marcar las promociones que fueron elegidos anteriormente
                    foreach (var item in qry_promociones_elegidas)
                    {
                        if (item.IdPromocion == promocion.IdPromocion)
                        {
                            art_prom.Elegido = true;
                            break;
                        }
                    }
                    art_prom.Descripcion = promocion.Descripcion;
                    art_prom.Estado = promocion.Estado;
                    art_prom.FechaFin = promocion.FechaFin;
                    art_prom.FechaInicio = promocion.FechaInicio;
                    art_prom.PorcentajeDescuento = promocion.PorcentajeDescuento;
                    art_prom.PuntosRequeridos = promocion.PuntosRequeridos;
                    art_prom.TipoCliente = promocion.TipoCliente;
                    lst_promociones.Add(art_prom);
                }
                programacionviaje.Promociones = lst_promociones;

                return View(programacionviaje);
            }
            catch
            {
                TempData["edit_failure"] = "No se encontró la programación de viaje";
                return RedirectToAction("Index");
            }
        }

        // POST: /ProgramacionViaje/Edit/5
        // Para protegerse de ataques de publicación excesiva, habilite las propiedades específicas a las que desea enlazarse. Para obtener 
        // más información vea http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include="IDProgramacionViaje,Productos,Choferes,Terramozas,Buses,Promociones,FechaSalida,Descripcion,CapacidadPasajeros,TipoServicio,Precio,Estado,FechaLlegada")] ProgramacionViaje programacionviaje)
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            if (ModelState.IsValid)
            {
                //validar choferes
                var choferes_seleccionados = programacionviaje.Choferes.Where(s => s.Elegido == true);
                if (choferes_seleccionados.Count() < 1)
                {
                    ModelState.AddModelError("ErrorMinChoferes", "Debe seleccionar como mínimo un Chofer");
                    return View(programacionviaje);
                }
                //validar terramozos
                var terramozos_seleccionados = programacionviaje.Terramozas.Where(s => s.Elegido == true);
                if (terramozos_seleccionados.Count() < 1)
                {
                    ModelState.AddModelError("ErrorMinTerramozos", "Debe seleccionar como mínimo una Terramoza/o");
                    return View(programacionviaje);
                }
                //validar terramozos
                var buses_seleccionados = programacionviaje.Buses.Where(s => s.Elegido == true);
                if (buses_seleccionados.Count() == 0 || buses_seleccionados.Count() >= 2)
                {
                    ModelState.AddModelError("ErrorMinBuses", "Debe seleccionar un Bus");
                    return View(programacionviaje);
                }
                //Asignación de buses a viajes
                foreach (var bus in programacionviaje.Buses)
                {
                    if (bus.Elegido)
                    {
                        //Guardar la Ruta_x_UnidadTrasporte 
                        programacionviaje.IdRuta_x_UnidadTransporte = bus.IDRutaxBus;
                        programacionviaje.Ruta_x_UnidadTransporte = db.Ruta_x_UnidadTransporte.Find(programacionviaje.IdRuta_x_UnidadTransporte);
                    }
                }
                //Asignación de choferes a viajes
                var qry_cho_prog = from per_prog in db.ProgramacionViaje_x_Personal
                                   join per in db.Persona on per_prog.IDPersona equals per.IDPersona
                                   where per.CargoPersonal=="Chofer" && per_prog.IDProgramacionViaje == programacionviaje.IDProgramacionViaje && per_prog.Estado == "AC"
                                   select per_prog;
                foreach (var item in qry_cho_prog)
                {
                    item.Estado = "AN";
                    db.Entry(item).State = EntityState.Modified;
                }
                foreach (var chofer in programacionviaje.Choferes)
                {
                    if (chofer.Elegido)
                    {
                        //Guardar en ProgramacionViaje_x_Personal
                        ProgramacionViaje_x_Personal per_progviaje = new ProgramacionViaje_x_Personal();
                        per_progviaje.IDPersona = chofer.IDPersona;
                        per_progviaje.IDProgramacionViaje = programacionviaje.IDProgramacionViaje;
                        per_progviaje.Estado = "AC";
                        db.ProgramacionViaje_x_Personal.Add(per_progviaje);
                    }
                }
                //Asignación de terramozas(os) a viajes
                var qry_terr_prog = from per_prog in db.ProgramacionViaje_x_Personal
                                    join per in db.Persona on per_prog.IDPersona equals per.IDPersona
                                    where per.CargoPersonal == "Terramoza/o" && per_prog.IDProgramacionViaje == programacionviaje.IDProgramacionViaje && per_prog.Estado == "AC"
                                    select per_prog;
                foreach (var item in qry_terr_prog)
                {
                    item.Estado = "AN";
                    db.Entry(item).State = EntityState.Modified;
                }
                foreach (var terr in programacionviaje.Terramozas)
                {
                    if (terr.Elegido)
                    {
                        //Guardar en ProgramacionViaje_x_Personal
                        ProgramacionViaje_x_Personal per_progviaje = new ProgramacionViaje_x_Personal();
                        per_progviaje.IDPersona = terr.IDPersona;
                        per_progviaje.IDProgramacionViaje = programacionviaje.IDProgramacionViaje;
                        per_progviaje.Estado = "AC";
                        db.ProgramacionViaje_x_Personal.Add(per_progviaje);
                    }
                }
                //Asignación de promociones a viajes
                var qry_prom_progv = from prom_prog in db.Promocion_ProgramacionViaje
                                     where prom_prog.IDProgramacionViaje == programacionviaje.IDProgramacionViaje && prom_prog.Estado == "AC"
                                     select prom_prog;
                foreach (var item in qry_prom_progv)
                {
                    item.Estado = "AN";
                    db.Entry(item).State = EntityState.Modified;
                }
                foreach (var prom in programacionviaje.Promociones)
                {
                    if (prom.Elegido)
                    {
                        //Guardar en Promocion_x_ProgramacionViaje
                        Promocion_ProgramacionViaje prom_progviaje = new Promocion_ProgramacionViaje();
                        prom_progviaje.IdPromocion = prom.IdPromocion;
                        prom_progviaje.IDProgramacionViaje = programacionviaje.IDProgramacionViaje;
                        prom_progviaje.Estado = "AC";
                        db.Promocion_ProgramacionViaje.Add(prom_progviaje);
                    }
                }

                //Modificar segun el cambio de estado
                switch (programacionviaje.Estado)
                {
                    case "PR":
                        //no hacer nada
                        break;
                    case "VI":
                        //Buscar ID de terminal de origen
                        var qry_nombre_TerminalOrigen = from ru_bu in db.Ruta_x_UnidadTransporte
                                                        join ru in db.Ruta on ru_bu.IDRuta equals ru.IDRuta
                                                        where ru_bu.IdRuta_x_UnidadTransporte == programacionviaje.IdRuta_x_UnidadTransporte
                                                        select ru;
                        Ruta TerminalOrig_EnRuta = qry_nombre_TerminalOrigen.First();
                        var qry_TerminalOrigen = from te in db.Terminal
                                                 where te.Nombre == TerminalOrig_EnRuta.TerminalOrigen
                                                 select te;
                        Terminal TerminalOrigen = qry_TerminalOrigen.First();
                        //Buscar almacenes, insertar movimiento y actualizar almacenes
                        foreach (var producto in programacionviaje.Productos)
                        {
                            //buscar almacen
                            var qry_almacen_origen = from al in db.Almacen
                                                     where al.IDProducto == producto.IDProducto && al.IDTerminal == TerminalOrigen.IDTerminal
                                                     select al;
                            Almacen almacen_origen = null;
                            try
                            {
                                almacen_origen = qry_almacen_origen.First();
                            }
                            catch
                            {
                                continue;
                            }
                            //insertar movimiento
                            Movimiento movimiento_salida = new Movimiento();
                            movimiento_salida.IdAlmacen = almacen_origen.IdAlmacen;
                            movimiento_salida.IDProgramacionViaje = programacionviaje.IDProgramacionViaje;
                            movimiento_salida.Cantidad = producto.Cantidad;
                            movimiento_salida.Tipo = 1; //movimiento de salida
                            db.Movimiento.Add(movimiento_salida);
                            //actualizar almacen 
                            almacen_origen.StockActual -= producto.Cantidad;
                            db.Entry(almacen_origen).State = EntityState.Modified;
                        }
                        
                        break;
                    case "CO":
                        //Buscar ID de terminal de destino
                        var qry_nombre_TerminalDestino = from ru_bu in db.Ruta_x_UnidadTransporte
                                                         join ru in db.Ruta on ru_bu.IDRuta equals ru.IDRuta
                                                         where ru_bu.IdRuta_x_UnidadTransporte == programacionviaje.IdRuta_x_UnidadTransporte
                                                         select ru ;
                        Ruta TerminalDest_EnRuta = qry_nombre_TerminalDestino.First();
                        var qry_TerminalDestino = from te in db.Terminal
                                                  where te.Nombre == TerminalDest_EnRuta.TerminalDestino
                                                  select te;
                        Terminal TerminaDestino = qry_TerminalDestino.First();
                        //Buscar almacenes, insertar movimiento y actualizar almacenes
                        foreach (var producto in programacionviaje.Productos)
                        {
                            //buscar almacen
                            var qry_almacen_destino = from al in db.Almacen
                                                     where al.IDProducto == producto.IDProducto && al.IDTerminal == TerminaDestino.IDTerminal
                                                     select al;
                            Almacen almacen_destino = null;
                            try
                            {
                                almacen_destino = qry_almacen_destino.First();
                            }
                            catch
                            {
                                continue;
                            }
                            //insertar movimiento
                            Movimiento movimiento_entrada = new Movimiento();
                            movimiento_entrada.IdAlmacen = almacen_destino.IdAlmacen;
                            movimiento_entrada.IDProgramacionViaje = programacionviaje.IDProgramacionViaje;
                            movimiento_entrada.Cantidad = producto.Cantidad;
                            movimiento_entrada.Tipo = 2; //movimiento de entrada
                            db.Movimiento.Add(movimiento_entrada);
                            //actualizar almacen 
                            almacen_destino.StockActual += producto.Cantidad;
                            db.Entry(almacen_destino).State = EntityState.Modified;
                        }
                        
                        break;
                }

                db.Entry(programacionviaje).State = EntityState.Modified;
                try
                {
                    db.SaveChanges();
                }
                catch
                {
                    TempData["edit_failure"] = "La programación viaje no se pudo modificar";
                    return RedirectToAction("Index");
                }
                TempData["edit_success"] = "La programación viajese modificó exitosamente";
                return RedirectToAction("Index");
            }
            
            return View(programacionviaje);
        }

        // GET: /ProgramacionViaje/Delete/5
        public ActionResult Delete(int? id)
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            try
            {
                ProgramacionViaje programacionviaje = db.ProgramacionViaje.Find(id);
                if (programacionviaje == null)
                {
                    return HttpNotFound();
                }

                return View(programacionviaje);
            }
            catch
            {
                TempData["delete_failure"] = "No se encontró la programación viaje";
                return RedirectToAction("Index");
            }
        }

        // POST: /ProgramacionViaje/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            ProgramacionViaje programacionviaje = db.ProgramacionViaje.Find(id);
            //Eliminar relacion del viaje con sus promociones
            var qry_prom = from prom_progv in db.Promocion_ProgramacionViaje
                           where prom_progv.IDProgramacionViaje == programacionviaje.IDProgramacionViaje
                           select prom_progv;
            foreach (var item in qry_prom)
            {
                item.Estado = "AN";
            }
            //Eliminar relacion del viaje con su personal
            var qry_personal = from progv_per in db.ProgramacionViaje_x_Personal
                               where programacionviaje.IDProgramacionViaje == progv_per.IDProgramacionViaje //incuye a terramozos y choferes
             
                               select progv_per;
            foreach (var item in qry_personal)
            {
                item.Estado = "AN";
            }
            //Eliminar el viaje (incluye la eliminacion del bus asociado)
            programacionviaje.Estado = "AN";
            db.Entry(programacionviaje).State = EntityState.Modified;
            try
            {
                db.SaveChanges();
            }
            catch
            {
                TempData["delete_failure"] = "La programación viaje no se pudo eliminar";
                return RedirectToAction("Index");
            }
            TempData["delete_success"] = "La programación viaje se eliminó exitosamente";
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
